﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.IO;
using NVelocity.App;
using NVelocity.Runtime;
using NVelocity;
using Commons.Collections;
using NVelocity.Context;
using System.Web;


namespace Cms.EntLib
{
    public class StringTemplate
    {
        private static VelocityEngine velocity = null;
        private IContext context = null;
        private bool CanBuildFile = false;
        private string TemplateDir = "";
        private string OutputUrl = "";
        private string template = "";

        private static object lockobj = new object();

        public StringTemplate() {
            if (velocity == null)
            {
                lock (lockobj)
                {
                    velocity = new VelocityEngine();
                    velocity.Init();
                }
            }            
            context = new VelocityContext();
        }
        public StringTemplate(string _template):this() {
            CanBuildFile = false;
            template = _template;
        }
        public StringTemplate(bool canBuildFile,string templatedir,string outputurl):this() { 
            CanBuildFile = canBuildFile;
            this.TemplateDir = templatedir;
            this.OutputUrl = outputurl;
            if (velocity == null) {
                lock (lockobj)
                {
                    velocity = new VelocityEngine();
                }
            }
            if (canBuildFile) {
                ExtendedProperties props = new ExtendedProperties();
                props.AddProperty(RuntimeConstants.RESOURCE_LOADER, "file");
                props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, HttpContext.Current.Server.MapPath(this.TemplateDir));
                props.AddProperty(RuntimeConstants.INPUT_ENCODING, "gb2312");
                props.AddProperty(RuntimeConstants.OUTPUT_ENCODING, "gb2312");
                velocity.Init(props);
                //为模板变量赋值
                context = new VelocityContext();
            }
        }
        /// <summary>
        /// 给模板变量赋值
        /// </summary>
        /// <param name="key">模板变量</param>
        /// <param name="value">模板变量值</param>
        public void Put(string key, object value)
        {
            if (context == null)
                context = new VelocityContext();
            context.Put(key, value);
        }

        public void Put(Dictionary<string,Object> kv){
            foreach (KeyValuePair<string, Object> k in kv) {
                Put(k.Key, k.Value);
            }
        }

        /// <summary>
        /// 显示模板
        /// </summary>
        /// <param name="templatFileName">模板文件名</param>
        public void Display(string templatFileName)
        {
            //从文件中读取模板
            Template template = velocity.GetTemplate(templatFileName);
            //合并模板
            StringWriter writer = new StringWriter();
            template.Merge(context, writer);
            //输出
            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.Write(writer.ToString());
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();
        }
        //根据模板替换所有的数据
        public string ReplaceAll() {
            if (CanBuildFile && !String.IsNullOrEmpty(this.TemplateDir))
            {
                Template template = velocity.GetTemplate(this.TemplateDir);
                //合并模板
                StringWriter writer = new StringWriter();
                template.Merge(context, writer);
                return writer.ToString();
            }
            else if (!String.IsNullOrEmpty(this.template))
            {
                System.IO.StringWriter vltWriter = new System.IO.StringWriter();
                velocity.Evaluate(context, vltWriter, null, this.template);
                return vltWriter.GetStringBuilder().ToString();
            }
            else
                return "";
        }
    }
}
